#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>

using namespace cv;

void laplacian_cpu(Mat &srcImg, Mat &dstImg, int imgHeight, int imgWidth)
{
  int Gx = 0;
  int Gy = 0;
  int gl = 0;
  //omp_set_num_threads(4);

  //#pragma omp parallel for
  for (int i = 1; i < imgHeight - 1; i++)
  {
    uchar *dataUp = srcImg.ptr<uchar>(i - 1);
    uchar *data = srcImg.ptr<uchar>(i);
    uchar *dataDown = srcImg.ptr<uchar>(i + 1);
    uchar *out = dstImg.ptr<uchar>(i);
    for (int j = 1; j < imgWidth - 1; j++)
    {
      //     Gx = (dataUp[j + 1] + 2 * data[j + 1] + dataDown[j + 1]) -
      //          (dataUp[j - 1] + 2 * data[j - 1] + dataDown[j - 1]);
      //     Gy = (dataUp[j - 1] + 2 * dataUp[j] + dataUp[j + 1]) -
      //          (dataDown[j - 1] + 2 * dataDown[j] + dataDown[j + 1]);
      //     out[j] = (abs(Gx) + abs(Gy)) / 2;

      gl = 4 * data[j] -
           data[j + 1] -
           data[j - 1] -
           //dataUp[j + 1] -
           //dataUp[j - 1] -
           dataUp[j] -
           //dataDown[j + 1] -
           //dataDown[j - 1] -
           dataDown[j];
      
      gl = gl * 2;
      if (gl <= 0)
      {
        gl = abs(gl);
      }
      if (gl > 255)
      {
        gl = 255;
      }
      out[j] = gl;
    }
  }
}

/** @函数 main */
int main(int argc, char **argv)
{
  Mat src, src_gray;
  int kernel_size = 3;
  int scale = 1;
  int delta = 0;
  int ddepth = CV_8UC1;
  std::string window_name = "Laplace Demo";

  int a1 = -525;
  unsigned char a3 = 5;
  int a4 = -257 / 256;
  unsigned char a2 = a1;
  printf("a2 = %d\n", a4);

  int c;

  /// 装载图像
  src = imread("/home/wuqi/code/vscode/vscode-test1/src/img1.png");

  if (!src.data)
  {
    return -1;
  }

  /// 使用高斯滤波消除噪声
  //GaussianBlur( src, src, Size(3,3), 0, 0, BORDER_DEFAULT );

  /// 转换为灰度图
  cvtColor(src, src_gray, CV_RGB2GRAY);

  /// 创建显示窗口
  namedWindow(window_name, 0);

  /// 使用Laplace函数
  Mat dst = cv::Mat(720, 1280, CV_8UC1, Scalar(0));
  Mat abs_dst, cv_dst;

  Laplacian(src_gray, cv_dst, ddepth, kernel_size, scale, delta, BORDER_DEFAULT);

  laplacian_cpu(src_gray, dst, 720, 1280);

  std::cout << "laplacian:" << int(dst.at<unsigned char>(200, 600)) << std::endl;

  printf("laplacian_ = %d\n", dst.at<unsigned char>(600, 600));

  convertScaleAbs(dst, abs_dst);

  cv::namedWindow("cv_dst", 0);
  cv::imshow("cv_dst", cv_dst);
  cv::waitKey(1);

  cv::namedWindow("gray", 0);
  cv::imshow("gray", src_gray);
  cv::waitKey(1);

  /// 显示结果
  imshow(window_name, abs_dst);

  waitKey(0);

  return 0;
}